GO
1. Shell函数的概念与作用介绍
简单地说,函数的作用就是将程序里多次被调用的相同代码组合起来(函数体),并为其取一个名字(即函数名),其它所有想重复调用这部分代码的地方都只需要调用这个名字就可以了。当需要修改这部分重复代码时,只需要改变函数体内的一份代码即可实现对所有调用的修改,也可以把函数独立地写到文件里,当需要调用函数时,再加载进来使用。
使用Shell函数的优势整理如下:
- 把相同的程序段定义成函数,可以减少整个程序的代码量,提升管理效率
- 增加程序的可读性、易读性,提升管理效率
- 可以实现程序功能模块化,使得程序具备通用性(可移植性)
对于Shell来说,Linux系统里的近2000个命令可以说都是Shell的函数,所以Shell的函数也是很多的,这一点需要注意一下。
2. Shell函数的语法
下面是Shell函数的常见语法格式:
标准写法为:
1234function 函数名(){ #<==推荐的书写函数的方法(带括号)指令...return n}简化写法1:在Shell函数的语法中,当有
function
时,函数名后面的小括号()
部分可以省略不写1234function 函数名{ #<==不推荐使用此方法(无括号)指令...return n}简化写法2:在Shell函数的语法中,
function
表示生命一个函数,这部分可以省略不写1234函数名(){ #<==不用function的方法指令...return n}
3. Shell函数的执行
Shell的函数分为最基本的函数和可传参的函数两种,其执行方式分别说明如下:
3.1. 基本函数的执行
执行不带参数的基本函数时,直接输入函数名即可(注意不带小括号)。格式如下:
有关执行函数的重要说明;
- 执行Shell函数时,函数名前的
function
和函数后的小括号都不要带 - 函数的定义必须在执行的程序前面定义或加载
- Shell执行系统中各种程序的执行顺序为:
系统别名
-函数
-系统命令
-可执行文件
- 函数执行时,会和调用它的脚本共用变量,也可以为函数设定局部变量及特殊位置参数
- 在Shell函数里面,
return
命令的功能与exit
类似,return
的作用是退出函数,而exit
是退出脚本文件 return
语句会返回一个退出值(即返回值)给调用函数的当前程序,而exit
会返回一个退出值(即返回值)给执行程序的当前Shell- 如果将函数存放在独立的文件中,被脚本加载使用,需要使用
source
或.
来加载 - 在函数内一般使用
local
定义局部变量,这些变量离开函数后就会消失
3.2. 带参数函数的执行
带参数的函数执行方法,格式如下:
函数后接参数的说明:
- Shell的位置参数(
$1
、$2
…、$#
、$*
、%$?
及$@
)都可以作为函数的参数来使用 - 此时父脚本的参数临时地被函数参数所掩盖或隐藏
$0
比较特殊,它仍然是父脚本的名称- 当函数执行完成时,原来的命令行脚本的参数即可恢复
- 函数的参数变量是在函数体里面定义的
4. Shell函数的基础实践
4.1. 范例1
开发脚本建立两个简单函数并调用执行
4.2. 范例2
分离函数体和执行函数的脚本文件(更规范的方法)
- 首先建立函数库脚本(默认不会执行函数)
使用
cat
命令追加多行文本,以将函数代码追加到系统的函数文件中,即/etc/init.d/functions
,命令如下:123456cat >> /etc/init.d/dunctions<<- EOF <==here文档的另一种写法,此写法允许后面的EOF可以使用Tab键,而不顶格theshu(){echo "I am theshu."}EOF然后开发执行脚本以调用上述函数:
123456#!/bin/bash# 加载函数所在文件(functions是Linux系统内置的脚本函数库)[ -f /etc/init.d/functions ] && . /etc/init.d/functions || exit 1# 提示:可以用source或.(点号)来加载脚本functions中的命令或变量参数等# 调用函数theshu
4.3. 范例3
写出带参数的Shell函数示例,这里通过建立函数theshu来做示例讲解。将函数的传参转换成脚本文件命令行传参,代码如下:
Shell中使用函数的编程思想
- 学习了函数以后应尽量将脚本功能模块化,每个模块实现一个功能,并让脚本可以通用。
- 当一个脚本实现了高度模块化,即用函数1、函数2、…、main函数、
main $*
传参,并能对其调用执行,这样的脚本的不但专业规范,而且看上去也很高大上,这些很值得花功夫去研究、学习和掌握。 - 实际使用时,一些基础的函数脚本(例如:加颜色的函数)是放在函数文件里的,例如放在
/etc/init.d/functions
里,与执行的内容部分相分离,这看起来更清爽,大型的语言程序都是这样开发的。
OK